4  Kapitel 4: Hypothesentests - Teil 1

In diesem Kapitel verwenden wir verschiedene Regressionsmodelle die zur Überprüfung von Hypothesen eingesetzt werden.

4.1 Vorbereitung

Install packages

if (!require("pacman")) install.packages("pacman")
Lade nötiges Paket: pacman
pacman::p_load(lmerTest, haven, brms, psych,
               sjmisc, sjPlot, sjlabelled, writexl, broom.mixed, qgraph,
               tidyverse, multilevelTools, parameters)

4.2 Daten einlesen

load("../data/df_example1.RData")
load("../data/df_example1c.RData")

Für diese Einheit verwenden wir den folgenden Datensatz (data.frame/tibble):

  • df_example1: Alle Skalenscores im Long Format, mit personen-zentrierten Variablenvarianten (“_dm”) und Personen-Mittelwerten der täglich gemessenenen Variablen (“_gm”). Struktur des Datensatzes kann man sich ansehen mit head() oder print().
head(df_example1)
id y m x y_dm m_dm x_dm y_gm m_gm x_gm
1 4.003538 4.769391 2.365486 -0.3020232 0.8945291 0.6845636 4.305561 3.874862 1.680922
1 4.925174 2.510943 0.748855 0.6196128 -1.3639189 -0.9320674 4.305561 3.874862 1.680922
1 4.598564 3.098112 1.395041 0.2930028 -0.7767499 -0.2858814 4.305561 3.874862 1.680922
1 4.286179 4.610746 1.860026 -0.0193822 0.7358841 0.1791036 4.305561 3.874862 1.680922
1 4.183494 4.549044 2.288019 -0.1220672 0.6741821 0.6070966 4.305561 3.874862 1.680922
1 3.631716 3.590049 1.696510 -0.6738452 -0.2848129 0.0155876 4.305561 3.874862 1.680922

Im Folgenden betrachten wir ein Modell in dem y durch x vorhergesagt wird.

4.3 Random Intercept Modell / Null-Model

Die Funktion lmer() benötigt zwei Argumente, (a) die Formel und (b) den Datensatz. Zum Aufbau und Details der Formeln s. Folien.

Level 1: \(y_{ij} = \beta_{0j} + e_{ij}\)

Level 2 (random intercept): \(\beta_{0j} = \gamma_{00} + u_{0j}\)

nullmodel <- lmer(y ~ (1 | id), data = df_example1)

Zur Ansicht der Ergebnisse haben wir zwei Optionen: Den summary() Befehl - die Standardansicht, wie von den Paketautoren implementiert, den tidy() Befehl aus dem broom-Package, und den model_parameters() Befehl aus dem parameters Package. tidy() und model_parameters() Funktionsoutputs könnten nach Excel/Word exportiert werden mittels der write_xlsx() Funktion, oder indem das Notebook als .docx “gerendert” (ausgegeben) wird.

summary(nullmodel)
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: y ~ (1 | id)
   Data: df_example1

REML criterion at convergence: 2742.9

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-6.1492 -0.5420 -0.0369  0.5543  4.6493 

Random effects:
 Groups   Name        Variance Std.Dev.
 id       (Intercept) 0.6902   0.8308  
 Residual             0.7164   0.8464  
Number of obs: 1000, groups:  id, 100

Fixed effects:
            Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)  5.36755    0.08728 99.00000    61.5   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
tidy(nullmodel)
effect group term estimate std.error statistic df p.value
fixed NA (Intercept) 5.3675530 0.0872832 61.49586 99 0
ran_pars id sd__(Intercept) 0.8307776 NA NA NA NA
ran_pars Residual sd__Observation 0.8464254 NA NA NA NA
model_parameters(nullmodel) |> print_html()
Model Summary
Parameter Coefficient SE 95% CI t(997) p
Fixed Effects
(Intercept) 5.37 0.09 (5.20, 5.54) 61.50 < .001
Random Effects
SD (Intercept: id) 0.83
SD (Residual) 0.85

Im Seminar verwenden wir den Output von model_parameters(), weil er eine recht gut formatierte Übersicht gibt.

4.3.1 ICC

Aus dem Null-Model wird der ICC bestimmt. Dies haben wir in der vorhergehenden

ICC: \(\frac{\tau_{00}}{\tau_{00}+\tau_{ij}}\), \(\tau\) gibt die Varianz des jewiligen Koeffizienten an.

Wir können dies aus dem Modelloutput nehmen und berechnen:

modelsummary <- model_parameters(nullmodel)
tau00 <- modelsummary$Coefficient[modelsummary$Parameter == "SD (Intercept)"]^2
tauij <- modelsummary$Coefficient[modelsummary$Parameter == "SD (Observations)"]^2
tau00 / (tau00+tauij)
[1] 0.4906711
# performance::icc(nullmodel) # Alternativfunktion

4.3.2 Visualisierung

Wir können uns die Analysen visualisieren, hier zur reduzierten visuellen Komplexität nur auf Basis der ersten 20 Personen (ID 1-20.)

Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
`geom_smooth()` using formula = 'y ~ x'

Oder zwei Personen, um uns die einzelnen Punkte auch anschauen zu können:

ggplot(data = df_example1 |> filter(id %in% c(1, 16)), aes(
  x = x,
  y = predicted_ri,
  colour = id
)) +
  geom_smooth(method = "lm", fullrange = TRUE, se = F, size = 1) +
  geom_jitter(aes(y = y), alpha = .5, size = 2.5) +
  labs(x = xlabel, y = ylabel) +
  ggtitle("Intercept-Only-Modell") +
  scale_colour_discrete() +
  geom_abline(intercept = fixef(nullmodel), slope = 0, size = 1.5) +
  ggthemes::theme_tufte()
`geom_smooth()` using formula = 'y ~ x'

4.4 Random Intercept, fixed slope Modell

Als nächstes bauen wir den Prädiktor x ein. Wir verwenden hier die zentrierte Variable “_dm” um Inner-Person Effekte zu berechnen.

Level 1: \(y_{ij} = \beta_{0j} + \beta_{1j} \cdot (X_{ij} - \bar{X_j}) + e_{ij}\)

Level 2 (random intercept): \(\beta_{0j} = \gamma_{00} + u_{0j}\)

Level 2 (fixed effect only): \(\beta'_{1j} = \gamma'_{10}\)

ri.fs_modell <- lmer(y ~ x_dm + (1 | id), data = df_example1)
model_parameters(ri.fs_modell) |> print_html()
Model Summary
Parameter Coefficient SE 95% CI t(996) p
Fixed Effects
(Intercept) 5.37 0.09 (5.20, 5.54) 61.50 < .001
x dm 0.44 0.04 (0.36, 0.51) 11.63 < .001
Random Effects
SD (Intercept: id) 0.84
SD (Residual) 0.79

4.4.1 Visualisierung

`geom_smooth()` using formula = 'y ~ x'

4.5 Random intercept, random slope Modell

Als nächstes fügen wir den random slope der Prädiktorvariable x_dm hinzu, in dem wir die random effect Struktur erweitern - “(1 + x_dm | id)”.

Level 1: \(y_{ij} = \beta_{0j} + \beta_{1j} \cdot (X_{ij}-\bar{X_j}) + e_{ij}\)

Level 2 (random intercept): \(\beta_{0j} = \gamma_{00} + u_{0j}\)

Level 2: \(\beta'_{1j} = \gamma'_{10}\)

ri.rs_modell <- lmer(y ~ x_dm + (1 + x_dm | id), data = df_example1)
model_parameters(ri.rs_modell) |> print_html()
Model Summary
Parameter Coefficient SE 95% CI t(994) p
Fixed Effects
(Intercept) 5.37 0.09 (5.20, 5.54) 61.50 < .001
x dm 0.42 0.07 (0.28, 0.56) 5.88 < .001
Random Effects
SD (Intercept: id) 0.85
SD (x_dm: id) 0.63
Cor (Intercept~x_dm: id) 0.20
SD (Residual) 0.65

4.5.1 Visualisierung

`geom_smooth()` using formula = 'y ~ x'

4.6 Level-2 Prädiktoren

Als nächstes fügen wir einen Level-2 Prädiktor hinzu, der pro Person nur einmal gemessen wurde. Dabei handelt es sich für gewöhnlich um (1) Variablen, bei denen wir nicht an täglichen Schwankungen interessiert sind, wie soziodemografischen oder Persönlichkeitsvariablen, oder (2) den Mittelwert der Personen auf einer täglich gemessenen Variable. Im Beispiel verwenden wir (2), “x_gm”.

Level 1: \(y_{ij} = \beta_{0j} + \beta_{1j} \cdot (X_{ij}-\bar{X_j}) + \beta_{2j}\cdot\bar{X_j} + e_{ij}\)

Level 2 (random intercept): \(\beta_{0j} = \gamma_{00} + u_{0j}\) Level 2 (random slope for x): \(\beta_{1j} = \gamma_{10} + u_{2j}\)

ri.rs_l2_modell <- lmer(y ~ x_dm + x_gm + (1 + x_dm | id), data = df_example1)
model_parameters(ri.rs_l2_modell) |> print_html()
Model Summary
Parameter Coefficient SE 95% CI t(993) p
Fixed Effects
(Intercept) 4.47 0.19 (4.09, 4.84) 23.30 < .001
x dm 0.42 0.07 (0.28, 0.56) 5.85 < .001
x gm 0.43 0.08 (0.26, 0.59) 5.13 < .001
Random Effects
SD (Intercept: id) 0.75
SD (x_dm: id) 0.63
Cor (Intercept~x_dm: id) 0.17
SD (Residual) 0.65

4.7 Übung

Wir arbeiten in der Übung mit einem neuen Datensatz.

Mache dich mit ihm vertraut. Diesmal benutzen wir einen Datensatz in dem die Variablen “labelled” sind, also Beschriftungen haben. Wir können die Labels mit get_label() oder view_df() abrufen.

load("../data/df_example_cli.RData")

head(df_example_cli)
id illtask negativ support illtask_dm negativ_dm illtask_gm negativ_gm negativ_dm_l1 day
1 1.188858 1.825857 3.454777 -1.2994333 -0.0153842 2.488291 1.841241 NA 1
1 1.719163 1.633681 3.454777 -0.7691283 -0.2075602 2.488291 1.841241 NA 4
1 3.149280 1.250429 3.454777 0.6609887 -0.5908122 2.488291 1.841241 NA 7
1 2.372508 1.583838 3.454777 -0.1157833 -0.2574032 2.488291 1.841241 -0.5908122 8
1 2.558448 2.912401 3.454777 0.0701567 1.0711598 2.488291 1.841241 -0.2574032 9
2 1.336438 2.111289 2.109855 0.2807496 -0.4911521 1.055688 2.602441 NA 1
view_df(df_example_cli)
Data frame: df_example_cli
ID Name Label Values Value Labels
1 id Personen-ID range: 1-100
2 illtask Daily Illegitimate Tasks range: -1.9-5.6
3 negativ Daily Negative Affect range: -0.2-7.7
4 support Coworker support range: 1.4-4.5
5 illtask_dm Illegitimate Tasks (person-mean centered) range: -2.1-2.3
6 negativ_dm Neg. Affect (person-mean centered) range: -2.0-2.7
7 illtask_gm Illegitimate Tasks (person average) range: -0.7-4.7
8 negativ_gm Neg. Affect (person average) range: 0.8-5.0
9 negativ_dm_l1 Previous-day Neg. Affect range: -2.0-2.7
10 day Tag (1-10) range: 1-10
# alternativ
#get_label(df_example_cli)

Berechne Modelle mit denen du die folgenden Hypothesen testest:

Hypothese 1: Tägliche illegitime Aufgaben hängen positiv mit täglichem negativem Affekt zusammen.

Teste zunächst ein Random intercept, fixed slope Modell, und dann ein Random Intercept, Random Slope Modell. Urteile, ob die Hypothese angenommen oder verworfen werden sollten.

ri.fs_modell <- lmer(negativ ~ illtask_dm + (1 | id), data = df_example_cli)
parameters(ri.fs_modell) |> print_html()
Package 'merDeriv' needs to be installed to compute confidence intervals
  for random effect parameters.
Model Summary
Parameter Coefficient SE 95% CI t(779) p
Fixed Effects
(Intercept) 2.73 0.07 (2.59, 2.87) 37.43 < .001
illtask dm 0.30 0.04 (0.23, 0.38) 8.07 < .001
Random Effects
SD (Intercept: id) 0.68
SD (Residual) 0.72
ri.rs_modell <- lmer(negativ ~ illtask_dm + (1 + illtask_dm | id), data = df_example_cli)
parameters(ri.rs_modell) |> print_html()
Model Summary
Parameter Coefficient SE 95% CI t(777) p
Fixed Effects
(Intercept) 2.73 0.07 (2.59, 2.87) 37.65 < .001
illtask dm 0.32 0.05 (0.22, 0.43) 6.37 < .001
Random Effects
SD (Intercept: id) 0.68
SD (illtask_dm: id) 0.35
Cor (Intercept~illtask_dm: id) 0.70
SD (Residual) 0.68

Die Hypothese 1 kann angenommen werden, da der Effekt von illegitimen Aufgaben (illtask_dm) signifikant positiv ist. Auch im strengeren random Slopes Modell ist der Effekt weiterhin signifikant.

Wir können auch sehen, dass im Random Slopes Modell die Konfidenzintervalle etwas breiter sind und der Standardfehler etwas grösser sind als im Fixed Slopes Modell. In Random Slopes Modellen können die Regressionskoeffizienten zwischen den Individuen variieren, was zusätzliche Varianz in die Schätzungen einbringt. Diese zusätzliche Unsicherheit führt dazu, dass sowohl die Standardfehler als auch die Konfidenzintervalle grösser ausfallen als in Fixed Slopes Modellen, bei denen die Steigung als konstant über alle Gruppen angenommen wird. Dadurch reflektieren die größeren Intervalle die höhere Unsicherheit in der Modellierung individueller Unterschiede in den Effekten.